package com.qqt.csr.route.service;

import com.qqt.csr.common.exception.StatusCode;
import com.qqt.csr.common.utils.ServiceAssert;
import com.qqt.csr.route.dto.resp.RouteResultDTO;
import com.qqt.csr.route.dto.resp.SkillSetDTO;
import com.qqt.csr.route.entity.RouteTask;
import com.qqt.csr.route.enums.RouteTaskEventEnum;
import com.qqt.csr.route.enums.SkillSetDistributionTypeEnum;
import com.qqt.csr.route.service.strategy.skillset.ISkillSetDistribution;
import com.qqt.csr.workbench.entity.SkillSet;
import com.qqt.csr.workbench.entity.SkillSetConfig;
import com.qqt.csr.workbench.service.SkillSetConfigService;
import com.qqt.csr.workbench.service.SkillSetService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 技能组分发
 */
@Slf4j
@Service
public class RouteSkillSetService {
    @Autowired
    private ServiceTimeService serviceTimeService;
    @Autowired
    private SkillSetConfigService skillSetConfigService;
    @Autowired
    private SkillSetService skillSetService;
    @Autowired
    private ConversationStatService conversationStatService;

    /**
     * 根据规则分发技能组
     *
     * @param routeTask
     */
    public void route(RouteTask routeTask, RouteResultDTO resultDTO, Integer distributeType) {
        routeTask.setSkillSet(null);
        if(CollectionUtils.isEmpty(routeTask.getPlanSkillSetIdList())){
            // 返回提示
            routeTask.addEvent(RouteTaskEventEnum.NOT_AVAILABLE_SKILL_SET);
            resultDTO.setContent("非服务时间");
            return;
        }

        List<SkillSetDTO> skillSetDTOList = getSkillSetDTOList(routeTask.getTenantId(), routeTask.getPlanSkillSetIdList());
        if (CollectionUtils.isEmpty(skillSetDTOList)) {
            // 返回提示
            routeTask.addEvent(RouteTaskEventEnum.NOT_AVAILABLE_SKILL_SET);
            resultDTO.setContent("非服务时间");
            return;
        }

        ISkillSetDistribution skillSetDistribution = getSkillSetDistribution(distributeType);
        SkillSetDTO skillSetDTO = skillSetDistribution.distribution(routeTask, skillSetDTOList);
        if (skillSetDTO == null) {
            // 返回提示
            routeTask.addEvent(RouteTaskEventEnum.NOT_AVAILABLE_SKILL_SET);
            resultDTO.setContent("非服务时间");
            return;
        }

        routeTask.bindSkillSet(skillSetDTO);
        resultDTO.setSkillSetDTO(skillSetDTO);

        // 记录业务规则分配技能组的会话数量
        conversationStatService.increaseConversationCount(routeTask.getTenantId(), skillSetDTO.getSkillSetId());
    }

    private ISkillSetDistribution getSkillSetDistribution(Integer distributeType) {
        SkillSetDistributionTypeEnum distributionTypeEnum = SkillSetDistributionTypeEnum.getByValue(distributeType);
        ServiceAssert.notNull(distributionTypeEnum, StatusCode.Common.NOT_EXIST.getCode(), "无效分配配置！", String.format("无效分配配置, bizId:%s", distributeType));
        return distributionTypeEnum.getSkillSetDistribution();
    }

    /**
     * 获取生效的技能组信息
     *
     * @param tenantId
     * @param skillSetIdList
     * @return
     */
    public List<SkillSetDTO> getSkillSetDTOList(String tenantId, List<Long> skillSetIdList) {
        Map<Long, SkillSetConfig> skillSetConfigMap = skillSetConfigService.queryBySkillSetId(skillSetIdList);
        Map<Long, SkillSet> skillSetMap = skillSetService.getSkillSetMap(tenantId);
        return skillSetIdList.stream()
                .map(skillSetConfigMap::get)
                .filter(Objects::nonNull)
                .filter(skillSetCfg -> skillSetMap.get(skillSetCfg.getSkillSetId()) != null)
                .map(skillSetCfg -> SkillSetDTO.builder()
                        .skillSetId(skillSetCfg.getSkillSetId())
                        .skillSetCfgId(skillSetCfg.getId())
                        .routePolicy(skillSetCfg.getRoutePolicy())
                        .build())
                .collect(Collectors.toList());
    }


}
